package com.boarsoft.message.store;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.boarsoft.message.bean.Message;
import com.boarsoft.message.bean.MessageEntity;
import com.boarsoft.message.bean.MessageQueryParam;

public interface MessageRoller {
	/**
	 * 
	 * @throws Exception
	 */
	void init() throws Exception;

	/**
	 * 将消息追加到存储中
	 * 
	 * @param m
	 * @return 消息ID（在存储中的）
	 * @throws Exception
	 */
	String append(Message m) throws Exception;

	/**
	 * 用于在移除队列时释放资源
	 */
	void close();

	/**
	 * 更新索引，将消息标记为成功或失败
	 * 
	 * @param id
	 * @param status
	 * @param tried
	 * @param memo
	 *            失败原因
	 * @return
	 * @throws Exception
	 */
	long update(String id, short status, int tried, String memo) throws Exception;

	/**
	 * 更新消息主记录的状态，将消息标记为成功或失败
	 * 
	 * @param m
	 * @param memo
	 * @return 
	 * @throws Exception
	 */
	long update(Message m, String memo) throws Exception;

	/**
	 * 更新某个收件人的状态
	 * 
	 * @param id
	 * @param recipient
	 * @param tried
	 * @param status
	 * @param memo
	 * @return
	 * @throws Exception
	 */
	long update(String id, String recipient, int tried, short status, String memo) throws Exception;

	/**
	 * 根据消息ID读取某一条消息，性能差，仅用于查询某一条具体的消息
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	MessageEntity read(String id) throws Exception;

	/**
	 * 从消息存储中读取一定数量的还未过期的消息，并标记为发送中
	 * 
	 * @param before
	 *            只装载本次执行时间之前产生的r消息（新产生的失败消息将在下一次执行时处理）
	 * @param after
	 *            过期的消息不查询出来
	 * @param status
	 *            指定消息状态
	 * @param limit
	 *            限制加载的数据量，此值总是 <= roller.pageSize
	 * @return 返回本次装载的消息数量
	 * @throws Exception
	 */
	List<MessageEntity> reload(Date before, Date after, short status, int limit) throws Exception;

	/**
	 * 删除term秒以前的消息（过期消息）
	 * 
	 * @param before
	 * @return
	 * @throws Exception
	 */
	int truncate(Date before) throws Exception;

	/**
	 * 一次恢复的消息数量
	 * 
	 * @return
	 */
	int getPageSize();

	/**
	 * 根据条件查询N笔消息
	 * 
	 * @param mqp
	 * @return
	 */
	List<MessageEntity> query(MessageQueryParam mqp);

	/**
	 * 统计消息条数
	 * 
	 * @param mqp
	 * @return
	 */
	List<Map<String, Object>> count(MessageQueryParam mqp);
}
